﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Data;
using Budgetsch.ViewModels.Costs;
using Budgetsch.Web.EntityModel;
using Budgetsch.Web.Services;
using GalaSoft.MvvmLight;

namespace Budgetsch.ViewModels.Costs
{
    public class CostsVM : ViewModelBase
    {
        #region Private members

        private readonly BudgetschDomainContext m_context;
        private PagedCollectionView m_costs = null;
        private bool m_isBusyLoadingCosts = true;
        private bool m_isBusyLoadingComments = true;
        private bool m_isInMonthMode = true;
        private int m_selectedYear;
        private int m_selectedMonth;

        #endregion

        #region Public properties

        public const string CostsPropertyName = "Costs";
        public const string IsBusyLoadingCostsPropertyName = "IsBusyLoadingCosts";
        public const string IsBusyLoadingCommentsPropertyName = "IsBusyLoadingComments";

        public PagedCollectionView Costs
        {
            get
            {
                return m_costs;
            }

            set
            {
                if (m_costs == value)
                {
                    return;
                }

                m_costs = value;
                RaisePropertyChanged(() => Costs);
            }
        }

        public bool IsBusyLoadingCosts
        {
            get
            {
                return m_isBusyLoadingCosts;
            }

            set
            {
                if (m_isBusyLoadingCosts == value)
                {
                    return;
                }

                m_isBusyLoadingCosts = value;
                RaisePropertyChanged(() => IsBusyLoadingCosts);
            }
        }

        public bool IsBusyLoadingComments
        {
            get
            {
                return m_isBusyLoadingComments;
            }

            set
            {
                if (m_isBusyLoadingComments == value)
                {
                    return;
                }

                m_isBusyLoadingComments = value;
                RaisePropertyChanged(() => IsBusyLoadingComments);
            }
        }

        public AddCostVM AddCostVM { get; set; }

        public ObservableCollection<Tuple<CostComment,string>> CostComments { get; set; }

        public bool IsInMonthMode
        {
            get { return m_isInMonthMode; }
            set
            {
                m_isInMonthMode = value;
                ChangeTimeframe();
            }
        }

        public int SelectedMonth
        {
            get { return m_selectedMonth; }
            set { m_selectedMonth = value; ChangeTimeframe(); }
        }
        public int SelectedYear
        {
            get { return m_selectedYear; }
            set { m_selectedYear = value; ChangeTimeframe(); }
        }

        #endregion

        public CostsVM()
        {
            m_context = new BudgetschDomainContext();
            m_context.Load(m_context.GetCostsForMonthQuery(DateTime.Now.Date.Month), x =>
            {
                IsBusyLoadingCosts = false;
                Costs = new PagedCollectionView(m_context.Costs);
                Costs.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
            }, new object());

            CostComments = new ObservableCollection<Tuple<CostComment, string>>();
            m_context.Load(m_context.GetCostCommentsQuery(), x =>
            {
                
                foreach (var c in m_context.CostComments)
                {
                    CostComments.Add(new Tuple<CostComment, string>(c, string.Format("{0}/{1}", c.Cost.CostCategory.Name, c.Cost.Description)));
                }
                IsBusyLoadingComments = false;
            }, new object());
            
            AddCostVM = new AddCostVM(m_context);
            IsInMonthMode = true;
        }

        #region Public methods

        public void RemoveCost(object o_)
        {
            var cost = o_ as Cost;
            if (cost != null)
            {
                m_context.Costs.Remove(cost);
            }
            m_context.SubmitChanges();
        }

        public AddCostVM GetNewAddCostVM()
        {
            var vm = new AddCostVM(m_context);
            vm.ItemAdded
                += () =>
                       {
                           m_context.Load(m_context.GetCostsForMonthQuery(DateTime.Now.Date.Month), x =>
                            {
                                IsBusyLoadingCosts = false;
                                Costs =
                                    new PagedCollectionView
                                        (m_context.Costs);
                                Costs.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                            }, new object());

                       };
            return vm;
        }

        public EditCostVM GetNewCostEditorVM(object p)
        {
            var cost = p as Cost;
            if (p != null)
            {
                return new EditCostVM(m_context, cost);
            }
            else throw new ArgumentException("Provided object must be an Cost item!");
        }

        public void AddCategory(string category_)
        {
            m_context.CostCategories.Add(new CostCategory() { Name = category_ });
            m_context.SubmitChanges();
        }

        public void RefreshCosts()
        {
            RaisePropertyChanged(() => Costs);
        }

        #endregion

        private void ChangeTimeframe()
        {
            IsBusyLoadingCosts = true;
            m_context.Costs.Clear();
            if (IsInMonthMode)
            {
                m_context.Load(m_context.GetCostsForMonthQuery(SelectedMonth), x =>
                {
                    IsBusyLoadingCosts = false;
                    Costs = new PagedCollectionView(m_context.Costs);
                    Costs.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
            else
            {
                m_context.Load(m_context.GetCostsForYearQuery(SelectedYear), x =>
                {
                    IsBusyLoadingCosts = false;
                    Costs = new PagedCollectionView(m_context.Costs);
                    Costs.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
        }
    }
}